﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpModelInterface.h"
#include "ElementId.h"
#include <set>

namespace gcmp
{
    /// \brief 强弱祖先对象查询
    struct GCMP_MODEL_INTERFACE_EXPORT ElementAncestorsQuery
    {
        /// \brief 构造函数
        ElementAncestorsQuery(const ElementId & who, int associateTraceBackGenerations = -1, int strongTraceBackGenerations = -1, int weakTraceBackGenerations = -1)
            : Who(who)
            , AssociateTraceBackGenerations(associateTraceBackGenerations)
            , StrongTraceBackGenerations(strongTraceBackGenerations)
            , WeakTraceBackGenerations(weakTraceBackGenerations)
        {}

        /// \brief 查询的对象
        ElementId Who;

        /// \brief 联合查询强弱的代数
        ///
        /// 同时沿着强父亲和弱父亲上溯。比如支持查询弱父亲的强父亲。
        /// -1表示所有，0表示不查询。
        /// 这个参数非0，则忽略StrongTraceBackGenerations和WeakTraceBackGenerations
        /// \note 查询的结果放在WeakAncestors集合。
        int AssociateTraceBackGenerations; 

        /// \brief 只沿着强父亲上溯的代数。-1表示所有，0表示不查询。
        int StrongTraceBackGenerations;

        /// \brief 只沿着强父亲上溯时查询到的强祖先
        std::set<ElementId> StrongAncestors;

        /// \brief 强关系及对应版本，此处的版本是本地缓存中的版本，不是云端最新版本，在缓存中找不到构件的版本时，用-1表示版本，如新建构件
        std::unordered_map<ElementId, Int32, ElementIdHash> StrongRelations;

        /// \brief 只沿着弱父亲上溯的代数。-1表示所有，0表示不查询。
        int WeakTraceBackGenerations; 

        /// \brief 只沿着弱父亲上溯时查询到的弱祖先；或者在联合查询时，查询到的祖先。
        std::set<ElementId> WeakAncestors;

        /// \brief 弱关系及对应版本，此处的版本是本地缓存中的版本，不是云端最新版本，在缓存中找不到构件的版本时，用-1表示版本，如新建构件
        std::unordered_map<ElementId, Int32, ElementIdHash> WeakRelations;
    };

    class IDocument;

    /// \brief Element对象关系工具
     class GCMP_MODEL_INTERFACE_EXPORT ElementRelationshipsUtils
    {
    public:
        /// \brief 查询对象的强弱关系祖先
        /// \param pDocument 文档指针。获取关系前文档会先更新关系。
        /// \param query 查询条件和结果
        /// \return 执行结果。参数非法返回false；需要查询的对象为空、代数为0，返回true
        static bool QueryAncestors(IDocument * pDocument, ElementAncestorsQuery & query);
    };
}
